from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.contrib import messages
from django.http import JsonResponse, HttpResponseForbidden
from django.utils import timezone
from django.urls import reverse
from django.db.models import Q, F
from django.views.decorators.http import require_POST
from django.db import IntegrityError
from datetime import timedelta

from ..models import ExamRoom, ExamRegistration, ExamPaper, ExamQuestion, Examinee
from ..decorators import examinee_required

@examinee_required
def profile(request):
    """考生个人信息页面"""
    examinee = request.examinee
    context = {
        'user': examinee,
        'profile': examinee,
    }
    return render(request, 'exam_system/profile.html', context)

@examinee_required
def available_exams(request):
    """显示可报名的考试列表"""
    examinee = request.examinee
    now = timezone.now()

    # 获取可报名的考场（考试开始前5分钟停止报名）
    exam_rooms = ExamRoom.objects.filter(
        (Q(status='preparing') | Q(status='in_progress')) &
        Q(start_time__gt=now + timedelta(minutes=5))
    ).order_by('start_time')

    # 检查考生是否已经报名
    for exam_room in exam_rooms:
        exam_room.is_registered = ExamRegistration.objects.filter(
            examinee=examinee,
            exam_room=exam_room
        ).exists()

    context = {
        'exam_rooms': exam_rooms,
        'user': examinee,
    }
    return render(request, 'exam_system/available_exams.html', context)

@examinee_required
@require_POST
def register_exam(request, exam_room_id):
    """报名参加考试"""
    examinee = request.examinee
    exam_room = get_object_or_404(ExamRoom, pk=exam_room_id)
    now = timezone.now()

    # 检查考试是否可以报名
    # 考试开始前5分钟停止报名
    if exam_room.status not in ['preparing', 'in_progress'] or \
       exam_room.start_time <= (now + timedelta(minutes=5)):
        messages.error(request, '该考试不可报名')
        return redirect('exam_system:available_exams')

    # 尝试创建报名记录
    try:
        ExamRegistration.objects.create(
            examinee=examinee,
            exam_room=exam_room,
            status='registered'
        )
        messages.success(request, f'成功报名《{exam_room.name}》')
    except IntegrityError:
        messages.warning(request, '您已经报名过这个考试了')
    except Exception as e:
        messages.error(request, f'报名失败：{str(e)}')

    return redirect('exam_system:available_exams')

@examinee_required
def dashboard(request):
    """考生仪表盘页面"""
    examinee = request.examinee
    now = timezone.now()

    # 获取可报名的考试（考试开始前5分钟停止报名）
    available_exam_rooms = ExamRoom.objects.filter(
        Q(status__in=['preparing', 'in_progress']) &
        Q(start_time__gt=now + timedelta(minutes=5))
    ).order_by('start_time')[:10]  # 只显示前10个可报名的考试

    # 检查考生是否已经报名这些考试
    for exam_room in available_exam_rooms:
        exam_room.is_registered = ExamRegistration.objects.filter(
            examinee=examinee,
            exam_room=exam_room
        ).exists()

    # 获取考生报名的所有考试
    registrations = ExamRegistration.objects.filter(examinee=examinee)

    # 分类考试状态
    upcoming_exams = []
    ongoing_exams = []
    finished_exams = []

    for reg in registrations:
        exam_room = reg.exam_room
        if exam_room.status == 'preparing' or (exam_room.status == 'in_progress' and exam_room.start_time > now):
            upcoming_exams.append(reg)
        elif exam_room.status == 'in_progress' and exam_room.start_time <= now and now <= exam_room.end_time:
            ongoing_exams.append(reg)
        elif exam_room.status == 'finished' or now > exam_room.end_time:
            finished_exams.append(reg)
        else:
            # 处理其他可能的状态
            finished_exams.append(reg)

    # 获取最近的考试（最多3个）
    recent_exams = []
    if upcoming_exams:
        recent_exams.extend(upcoming_exams[:2])
    if ongoing_exams and len(recent_exams) < 3:
        recent_exams.extend(ongoing_exams[:3 - len(recent_exams)])
    if finished_exams and len(recent_exams) < 3:
        recent_exams.extend(finished_exams[:3 - len(recent_exams)])

    # 更新考试状态
    for reg in recent_exams:
        if now > reg.exam_room.end_time:
            reg.exam_room.status = 'finished'
            reg.exam_room.save()

    # 获取最近的考试成绩（最多3个）
    recent_results = []
    for reg in finished_exams[:3]:
        if hasattr(reg, 'exam_paper') and reg.exam_paper:
            recent_results.append({
                'exam_name': reg.exam_room.name,
                'score': reg.exam_paper.total_score,
                'total': reg.exam_room.total_score,
                'date': reg.exam_paper.submitted_at or reg.exam_room.end_time
            })

    # 计算考试完成情况
    total_exams_count = len(registrations)
    completed_exams_count = len([reg for reg in registrations if reg.status == 'completed'])
    completed_exams_percentage = (completed_exams_count / total_exams_count * 100) if total_exams_count > 0 else 0

    # 获取通知信息
    notifications = []  # 如果有通知系统，从这里获取通知

    context = {
        'upcoming_exams': upcoming_exams,
        'ongoing_exams': ongoing_exams,
        'finished_exams': finished_exams,
        'recent_exams': recent_exams,
        'recent_results': recent_results,
        'available_exam_rooms': available_exam_rooms,
        'user': examinee,
        'total_exams_count': total_exams_count,
        'completed_exams_count': completed_exams_count,
        'completed_exams_percentage': completed_exams_percentage,
        'notifications': notifications,
    }

    return render(request, 'exam_system/dashboard.html', context)

@examinee_required
def exam_list(request):
    """显示考生的考试列表"""
    examinee = request.examinee
    now = timezone.now()

    # 获取考生报名的所有考试
    registrations = ExamRegistration.objects.filter(examinee=examinee)

    # 分类考试状态
    upcoming_exams = []
    ongoing_exams = []
    finished_exams = []

    for reg in registrations:
        exam_room = reg.exam_room

        # 添加试卷信息（如果存在）
        try:
            reg.exam_paper = ExamPaper.objects.get(exam_room=exam_room, examinee=examinee)
        except ExamPaper.DoesNotExist:
            reg.exam_paper = None

        # 添加题型信息
        reg.question_types = []
        if exam_room.single_choice_count > 0:
            reg.question_types.append(f"单选题{exam_room.single_choice_count}道（{exam_room.single_choice_score}分/道）")
        if exam_room.multiple_choice_count > 0:
            reg.question_types.append(f"多选题{exam_room.multiple_choice_count}道（{exam_room.multiple_choice_score}分/道）")
        if exam_room.judgment_count > 0:
            reg.question_types.append(f"判断题{exam_room.judgment_count}道（{exam_room.judgment_score}分/道）")

        # 根据考试状态分类
        if exam_room.status == 'preparing' or (exam_room.status == 'in_progress' and exam_room.start_time > now):
            upcoming_exams.append(reg)
        elif exam_room.status == 'in_progress' and exam_room.start_time <= now and now <= exam_room.end_time:
            ongoing_exams.append(reg)
        else:
            finished_exams.append(reg)

    context = {
        'upcoming_exams': upcoming_exams,
        'ongoing_exams': ongoing_exams,
        'finished_exams': finished_exams,
    }

    return render(request, 'exam_system/exam_list.html', context)

@examinee_required
def take_exam(request, exam_room_id):
    """考试答题页面"""
    examinee = request.examinee
    exam_room = get_object_or_404(ExamRoom, pk=exam_room_id)
    now = timezone.now()

    # 检查考生是否已报名该考试
    registration = get_object_or_404(ExamRegistration, examinee=examinee, exam_room=exam_room)

    # 检查考试状态和时间
    if not exam_room.is_active:  # 使用模型的 is_active 属性
        if exam_room.status != 'in_progress':
            messages.warning(request, '考试尚未开始')
        elif now < exam_room.start_time:
            time_to_start = (exam_room.start_time - now).total_seconds()
            if time_to_start > 300:  # 如果距离开始还有超过5分钟
                messages.info(request, f'考试将于 {exam_room.start_time.strftime("%Y-%m-%d %H:%M")} 开始')
            else:
                messages.info(request, '考试即将开始，请耐心等待')
        elif now > exam_room.end_time:
            messages.warning(request, '考试已结束')
        return redirect('exam_system:exam_list')

    # 获取或创建试卷
    try:
        exam_paper = ExamPaper.objects.get(exam_room=exam_room, examinee=examinee)
        if exam_paper.is_submitted:  # 如果试卷已提交，跳转到结果页面
            return redirect('exam_system:exam_result', exam_room_id=exam_room_id)

        # 检查考试是否超时(10分钟无活动自动提交)
        if (now - exam_paper.last_active_time).total_seconds() > 600:
            exam_paper.is_submitted = True
            exam_paper.submitted_at = now
            exam_paper.save()
            messages.warning(request, '考试因长时间无操作已自动提交')
            return redirect('exam_system:exam_result', exam_room_id=exam_room_id)

    except ExamPaper.DoesNotExist:
        # 如果试卷不存在，可能是定时任务尚未创建，手动创建
        exam_paper = ExamPaper.generate_paper(exam_room, examinee)

    # 计算距离开始时间还有多少秒
    time_to_start = 0
    can_start = True
    if now < exam_room.start_time:
        time_to_start = int((exam_room.start_time - now).total_seconds())
        can_start = False
    elif exam_room.status != 'in_progress':
        can_start = False

    context = {
        'exam_room': exam_room,
        'exam_paper': exam_paper,
        'can_start': can_start,
        'time_to_start': time_to_start,
        'exam_started': False,  # 默认为未开始状态
    }

    return render(request, 'exam_system/take_exam.html', context)

@examinee_required
@require_POST
def submit_answer(request):
    """提交单个题目的答案"""
    examinee = request.examinee
    question_id = request.POST.get('question_id')
    answer = request.POST.get('answer')

    # 获取题目
    exam_question = get_object_or_404(ExamQuestion, pk=question_id)

    # 检查该题目是否属于该考生
    if exam_question.paper.examinee != examinee:
        return JsonResponse({'status': 'error', 'message': '无权提交此答案'}, status=403)

    # 检查考试是否在进行中
    exam_room = exam_question.paper.exam_room
    now = timezone.now()
    if exam_room.status != 'in_progress' or now < exam_room.start_time or now > exam_room.end_time:
        return JsonResponse({'status': 'error', 'message': '考试不在进行中'}, status=400)

    # 检查试卷是否已提交
    if exam_question.paper.is_submitted:
        return JsonResponse({'status': 'error', 'message': '试卷已提交，无法修改'}, status=400)

    # 保存答案
    try:
        # 对于判断题，统一答案格式
        if exam_question.question.question_type == 'judge':
            answer = 'T' if answer.upper() in ['T', 'TRUE', '1','正确'] else 'F'
        exam_question.submit_answer(answer)
        return JsonResponse({
            'status': 'success',
            'message': '答案已保存',
            'question_number': exam_question.question_number
        })
    except Exception as e:
        return JsonResponse({'status': 'error', 'message': str(e)}, status=500)

@examinee_required
@require_POST
def submit_exam(request, paper_id):
    """提交整份试卷"""
    examinee = request.examinee

    # 获取试卷
    exam_paper = get_object_or_404(ExamPaper, pk=paper_id)

    # 检查该试卷是否属于该考生
    if exam_paper.examinee != examinee:
        return JsonResponse({'status': 'error', 'message': '无权提交此试卷'}, status=403)

    # 检查试卷是否已提交
    if exam_paper.is_submitted:
        return JsonResponse({'status': 'error', 'message': '试卷已提交'}, status=400)

    # 提交试卷
    exam_paper.is_submitted = True
    exam_paper.submitted_at = timezone.now()
    exam_paper.save()

    # 更新考试报名状态
    registration = ExamRegistration.objects.get(examinee=examinee, exam_room=exam_paper.exam_room)
    registration.status = 'completed'
    registration.save()

    return JsonResponse({
        'status': 'success',
        'message': '试卷提交成功',
        'redirect_url': reverse('exam_system:exam_result', args=[exam_paper.exam_room.id])
    })

@examinee_required
def exam_detail(request, exam_room_id):
    """考试答案详情查看页面"""
    examinee = request.examinee
    exam_room = get_object_or_404(ExamRoom, pk=exam_room_id)

    # 获取考生的试卷
    exam_paper = get_object_or_404(ExamPaper, exam_room=exam_room, examinee=examinee)

    # 检查考试是否已结束或试卷已提交
    if not exam_paper.is_submitted and exam_room.status == 'in_progress':
        return redirect('exam_system:exam_list')

    # 获取所有题目，按题号排序
    exam_questions = exam_paper.questions.all().order_by('question_number')

    # 计算正确率
    total_questions = exam_questions.count()
    correct_questions = exam_questions.filter(is_correct=True).count()
    correct_rate = (correct_questions / total_questions * 100) if total_questions > 0 else 0

    context = {
        'exam_room': exam_room,
        'exam_paper': exam_paper,
        'exam_questions': exam_questions,
        'correct_rate': correct_rate
    }

    return render(request, 'exam_system/exam_detail.html', context)

@examinee_required
def exam_result(request, exam_room_id):
    """考试结果页面"""
    examinee = request.examinee
    exam_room = get_object_or_404(ExamRoom, pk=exam_room_id)

    # 获取考生的试卷
    exam_paper = get_object_or_404(ExamPaper, exam_room=exam_room, examinee=examinee)

    # 如果试卷未提交且考试仍在进行中，重定向到答题页面
    now = timezone.now()
    if not exam_paper.is_submitted and exam_room.status == 'in_progress' and now <= exam_room.end_time:
        return redirect('exam_system:take_exam', exam_room_id=exam_room_id)

    # 计算统计信息
    total_questions = exam_paper.questions.count()
    answered_questions = exam_paper.questions.exclude(answer__isnull=True).count()
    correct_questions = exam_paper.questions.filter(is_correct=True).count()

    # 按题型分类统计
    question_stats = {
        'single': {
            'total': exam_paper.questions.filter(question__question_type='single').count(),
            'correct': exam_paper.questions.filter(question__question_type='single', is_correct=True).count(),
        },
        'multiple': {
            'total': exam_paper.questions.filter(question__question_type='multiple').count(),
            'correct': exam_paper.questions.filter(question__question_type='multiple', is_correct=True).count(),
        },
        'judge': {
            'total': exam_paper.questions.filter(question__question_type='judge').count(),
            'correct': exam_paper.questions.filter(question__question_type='judge', is_correct=True).count(),
        }
    }

    context = {
        'exam_room': exam_room,
        'exam_paper': exam_paper,
        'total_questions': total_questions,
        'answered_questions': answered_questions,
        'correct_questions': correct_questions,
        'accuracy_rate': round(correct_questions / total_questions * 100, 2) if total_questions > 0 else 0,
        'question_stats': question_stats,
    }

    return render(request, 'exam_system/exam_result.html', context)

@examinee_required
@require_POST
def keep_alive(request, exam_paper_id):
    """保持考试活动状态的API"""
    examinee = request.examinee
    try:
        exam_paper = ExamPaper.objects.get(id=exam_paper_id, examinee=examinee)
        if not exam_paper.is_submitted:
            exam_paper.save()  # 自动更新last_active_time
            return JsonResponse({'status': 'success'})
        return JsonResponse({'status': 'error', 'message': '考试已提交'}, status=400)
    except ExamPaper.DoesNotExist:
        return JsonResponse({'status': 'error', 'message': '试卷不存在'}, status=404)

@examinee_required
def check_exam_status(request):
    """检查考试状态的API，用于前端轮询"""
    examinee = request.examinee
    now = timezone.now()

    # 获取考生报名的所有考试
    registrations = ExamRegistration.objects.filter(examinee=examinee)

    # 检查是否有新开始的考试
    newly_started = []
    for reg in registrations:
        exam_room = reg.exam_room
        if exam_room.status == 'in_progress' and exam_room.start_time <= now and now <= exam_room.end_time:
            newly_started.append({
                'id': exam_room.id,
                'name': exam_room.name,
                'start_time': exam_room.start_time.strftime('%Y-%m-%d %H:%M'),
                'end_time': exam_room.end_time.strftime('%Y-%m-%d %H:%M'),
            })

    # 检查是否有刚结束的考试
    newly_ended = []
    for reg in registrations:
        exam_room = reg.exam_room
        if exam_room.status == 'in_progress' and now > exam_room.end_time:
            newly_ended.append({
                'id': exam_room.id,
                'name': exam_room.name,
            })

    return JsonResponse({
        'status': 'success',
        'newly_started': newly_started,
        'newly_ended': newly_ended,
    })